.

iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0
Mobile Development

RxSwift / 30天探索之旅系列 第 13

第 13 天 - Combining Observables(上)

  • 分享至 

  • xImage
  •  

今天講講Combining operator,因為我們常常要合併多個Oberservable,藉此來獲得(分享)想要的資料,但Observable概念就像資料流,隨時間在走跳,所以依照情境來選擇operator是很重要的,Combining operator有好幾個,每個又都好重要,所以,我們分幾天介紹,附上範例,邊走邊講吧!

Combining operator有分為合併元素跟合併Observable,我們今天就先從合併元素的講起。

Reduce

reduce跟swift的reduce用法相同,都是給定初始值,尋訪每個元素,去做累加的動作。

let subject = PublishSubject<Int>()

let observable = subject.reduce(0) { summary, newValue in
    return summary + newValue
}

observable
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: disposeBag)

subject.onNext(1)
subject.onNext(3)
subject.onNext(5)
subject.onNext(7)
subject.onNext(9)

subject.onCompleted()

執行結果

25

值得大家注意的一點是,reduce會直到接收到.Completed才會開始執行,並且,只會回傳最後的結果,這點要特別注意。

Scan

reduce超像,差別在於.scan不需要接收到.Completed才執行

let subject = PublishSubject<Int>()

let observable = subject.scan(0) { summary, newValue in
    return summary + newValue
}

observable
    .subscribe(onNext: { value in
        print(value)
    })
    .disposed(by: disposeBag)

subject.onNext(1)
subject.onNext(3)
subject.onNext(5)
subject.onNext(7)
subject.onNext(9)

執行結果

1
4
9
16
25

所以,print會將每一個步驟列印出,並且,不用收到.Completed才執行,這是跟reduce差異最大的地方,也因為這樣,通常情況下我也會使用scan,相較之下比較靈活。

StartWith

startWith就像是簡單版的concat,在Observable發送之前,給定一個預設值。

let subject = PublishSubject<Void>()

let observable = subject.asObservable().startWith(())

observable
    .subscribe(onNext: {
        print("Do something.")
    })
    .disposed(by: disposeBag)

執行結果

Do something.

在沒發出任何元素的狀況下,預先發了一個預設值。

小疑惑

大家有沒有想過,我就用 BehaviorSubject 帶預設值就好啊!為什麼要用startWith
這是我一開始學的疑惑,的確以上這情境達到的結果是一樣的,但概念上不一樣,BehaviorSubject概念是訂閱時可以拿到上一個值,startWith就只是在最一開始發出一預設值,假設我們在程式後面加上

delay(1) {
    observable
        .subscribe(onNext: {
            print("Do something. \($0)")
        })
        .disposed(by: self.disposeBag)
}

這個情境下,BehaviorSubject仍然可以拿到上一個元素,而startWith卻拿不到,這時候結果就不一樣了。

我覺得這是Rx很妙的地方,你可能用錯operator程式當下也是好好的,但某個情境下就跑出問題,唯有瞭解每一個operator,依據情境去做選擇才是正解!


今天講了幾個Combine Element的operator,明天會繼續介紹Combine Observable,以上,明天見!


上一篇
第 12 天 - Share & ShareReplay
下一篇
第 14 天 - Combining Observables(中)
系列文
RxSwift / 30天探索之旅30
.
圖片
  直播研討會

尚未有邦友留言

立即登入留言